iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0
JavaScript

用 TypeScript 重新定義前端開發:30 天的實踐與思考系列 第 21

Day21:使用 TypeScript 與 Redux,為 action 和 reducer 定義型別

  • 分享至 

  • xImage
  •  

Redux 是一個在 React 應用程式中常用的狀態管理工具,能夠有效地管理大型應用中的全域狀態。當我們使用 TypeScript 與 Redux 時,型別支持能幫助我們避免常見的錯誤,並提供更好的開發體驗。在今天的文章中,將介紹如何為 actionreducer 定義型別,做到更加健壯 Redux 程式碼的效果。

一、什麼是 Action 和 Reducer?

在 Redux 中,action 是一個 JavaScript 物件,描述了希望發生的事情(如更新狀態)。而 reducer 則是一個函式,根據接收到的 action 來更新狀態。

舉個例子,如果我們有一個簡單的計數器應用,當我們點擊按鈕時,計數器的當前值會增加或減少。這些「增加」和「減少」的行為就是我們的 action,而更新狀態的邏輯就是 reducer

二、為 Action 定義型別

我們通常會根據應用的不同需求定義多個 action,而使用 TypeScript,可以為每個 action 定義型別。

1. 定義 Action 型別

假我們有兩個 action:一個是 INCREMENT 用來增加計數、另一個是 DECREMENT 用來減少計數。

// 定義 Action 的字面量型別
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';

// 定義 Action 物件的型別
interface IncrementAction {
  type: typeof INCREMENT;
}

interface DecrementAction {
  type: typeof DECREMENT;
}

// 使用聯合型別定義可能的所有 Action
export type CounterActionTypes = IncrementAction | DecrementAction;

2. 實現 Action 創建函式

為了方便使用,通常會建立「Action 創建函式」來生成 action 物件。這樣可以讓程式碼更易於維護且確保型別正確。

// Action 創建函式
export const increment = (): IncrementAction => ({
  type: INCREMENT,
});

export const decrement = (): DecrementAction => ({
  type: DECREMENT,
});

三、為 Reducer 定義型別

reducer 是負責根據 action 來更新應用狀態的函式。在 Redux 中,reducer 會根據當前的狀態以及接收到的 action 來決定如何更新狀態。

1. 定義狀態型別

首先是定義狀態的型別:

// 定義計數器的狀態型別
export interface CounterState {
  count: number;
}

2. 實現 Reducer

接下來,則是定義 reducer,來處理不同的 action 並更新狀態。先將 action 的型別指定為 CounterActionTypes,這樣 TypeScript 可以協助檢查每個 action 是否符合預期。

// 初始狀態
const initialState: CounterState = {
  count: 0,
};

// 定義 reducer
export const counterReducer = (
  state: CounterState = initialState,
  action: CounterActionTypes
): CounterState => {
  switch (action.type) {
    case INCREMENT:
      return {
        ...state,
        count: state.count + 1,
      };
    case DECREMENT:
      return {
        ...state,
        count: state.count - 1,
      };
    default:
      return state;
  }
};
  • initialState 是我們的初始狀態,計數器初始值為 0。
  • reducer 中,我們使用 switch 語句根據不同的 action.type 來決定如何更新狀態。
  • 如果 action.typeINCREMENT,我們就將 count 增加 1;如果是 DECREMENT,我們就減少 1。
  • 最後,如果 action.type 不是我們定義的 actionreducer 會返回當前的狀態,不做任何改變。

四、在 React 中使用 TypeScript 和 Redux

最後,來看看如何在 React 中結合 TypeScript 和 Redux 吧!

假設已經配置好 Redux 的 store,可以使用 useDispatchuseSelector 來調用 action 並從狀態中取得數值。

import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increment, decrement } from './actions';
import { CounterState } from './reducers';

function Counter() {
  const dispatch = useDispatch();
  const count = useSelector((state: CounterState) => state.count);

  return (
    <div>
      <p>當前值: {count}</p>
      <button onClick={() => dispatch(increment())}>增加</button>
      <button onClick={() => dispatch(decrement())}>減少</button>
    </div>
  );
}

export default Counter;
  • useDispatch 用來發送 action(在這個範例,是發送 incrementdecrement)。
  • useSelector 用來從全域狀態中選取需要的 count 值。
  • 當按下按鈕時,計數器會根據 action 增加或減少。

五、結語

使用 TypeScript 與 Redux,可以讓我們的狀態管理更加健壯,避免錯誤的 action 或狀態更新。


上一篇
Day20:使用 TypeScript 為 React Hooks 增加型別註記
下一篇
Day22:使用 TypeScript 為 React 元件定義複雜的型別
系列文
用 TypeScript 重新定義前端開發:30 天的實踐與思考30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言